//
//  demo.cpp
//  Test
//
//  Created by xgc on 12/15/17.
//  Copyright © 2017 xgc. All rights reserved.
//

#include <stdio.h>
#include "demo.h"

#include <bitcoin/bitcoin.hpp>
#include <assert.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>

#include "libcperciva/util/humansize.h"
#include "libcperciva/util/insecure_memzero.h"
#include "lib/scryptenc/scryptenc.h"

#include "utils/CoinType.h"


using namespace std;


using namespace bc;
using namespace bc::wallet;


int random_number(uint8_t array[16], int len)
{
    static int dev_random_fd = -1;
    char *next_random_byte;
    int bytes_to_read;
    
    
    if (dev_random_fd == -1)
    {
        dev_random_fd = open("/dev/urandom", O_RDONLY);
        assert(dev_random_fd != -1);
    }
    
    next_random_byte = (char *)&array[0];
    bytes_to_read = len;
    
    
    do
    {
        int bytes_read;
        bytes_read = read(dev_random_fd, next_random_byte, bytes_to_read);
        bytes_to_read -= bytes_read;
        next_random_byte += bytes_read;
        
        bc::cout << bytes_read << std::endl;
    }while(bytes_to_read > 0);
    
    return 0;
}

void test()
{
    //CoinType ct = CoinType::BTC;
    
    uint8_t arr[16] = {0};
    
    int n = random_number(arr, 16);
    std::vector<uint8_t> v(&arr[0], &arr[16]);
    
    for(int i = 0; i < 16; i++)
    {
        bc::cout << arr[i] << std::endl;
    }
    
    
    data_slice entropy = v;
    bc::cout << entropy.size() << std::endl;
    word_list wl = create_mnemonic(entropy);
    
    for (const auto& word: wl)
    {
        bc::cout << word << std::endl;
    }
    
    bool bOK = validate_mnemonic(wl, language::en);
    if(bOK)
    {
        bc::cout << bOK << std::endl;
    }
    
    const auto seed = decode_mnemonic(wl);
    std::string strSeed = "";
    for (const auto& b: seed)
    {
        char data[3] = {0};
        sprintf(data, "%02x", b);
        
        strSeed += data;
    }
    bc::cout << strSeed << std::endl;
    
    strSeed = "000102030405060708090a0b0c0d0e0f";
    
    data_chunk dc;
    
    decode_base16(dc, strSeed);
    
    //dc = to_chunk(seed);
    
    const hd_private m(dc, hd_private::mainnet);
    bc::cout << m.encoded() << std::endl;
    bc::cout << m.to_public().encoded() << std::endl;
    bc::cout << "-----------------------------------------111-------------" << std::endl;
    
    
    const auto m0 = m.derive_private(hd_first_hardened_key);
    bc::cout << m0.encoded() << std::endl;
    
    const auto p0 = m.derive_public(hd_first_hardened_key);
    bc::cout << p0.encoded() << std::endl;
    
    const hd_public p = m0.to_public();
    bc::cout << p.encoded() << std::endl;
    
    bc::cout << "-----------------------------------------222-------------" << std::endl;
    
    const auto m01 = m0.derive_private(1);
    bc::cout << m01.encoded() << std::endl;
    
    const auto p1 = m0.derive_public(1);
    bc::cout << p1.encoded() << std::endl;
    
    const hd_public p01 = m01.to_public();
    bc::cout << p01.encoded() << std::endl;
    
    
    ec_secret ecs = m01.secret();
    
    ec_private ecp1(ecs);
    
    bc::cout << ecp1.encoded() << std::endl;
    
    
    ec_compressed ecc = p01.point();
    
    ec_public ecp(ecc);
    
    payment_address addr = ecp.to_payment_address();
    string address = addr.encoded();
    bc::cout << addr.encoded() << std::endl;
}

void test2()
{
    /*
    size_t maxmem = 0;
    double maxmemfrac = 0.5;
    double maxtime = 6.0;
    const char* passwd = "12345";
    
    int rc;
    
    maxmem = 0;
    maxmemfrac = 0.125;
    maxtime = 1.0;
    
    const char* inbuf = "abcdefghijklmnopqrstuvwxyz";
    char outbuf[1024] = {0};
    size_t outlen = 0;
    uint8_t dk[64] = {0};
    
    
    rc = scryptenc_buf((const uint8_t *)inbuf, strlen(inbuf), (uint8_t *)outbuf, &outlen,
                       (const uint8_t *)passwd, 5,
                       15, 8, 1, dk);
    
    printf("--------------\n");
    
    if (rc != 0) {
        return;
    }
    
    for(int i = 0; i < outlen; i++)
    {
        printf("%02x ", (unsigned char)outbuf[i]);
    }
    
    printf("\n");
    
    char buf[1024] = {0};
    size_t len = 0;
    rc = scryptdec_buf((const uint8_t *)outbuf, outlen, (uint8_t *)buf,
                       &len, (const uint8_t *)dk, (const uint8_t *)&dk[32]);
    
    printf("length:%ld\n", len);
    printf("%s\n", buf);
    */
}
